package com.kevin.service;

import com.alibaba.fastjson.JSON;
import com.kevin.algorithm.*;
import com.kevin.model.Location;
import com.kevin.utils.PointsRep;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author kevin
 * @version V1.0
 * @Description: TODO
 * @date 2019/1/30 13:34
 **/
@Service
public class CalculateData {
    private static final Logger LOGGER = LoggerFactory.getLogger(CalculateData.class);
    /**
     * 数据仓库
     */
    private PointsRep pointsRep = new PointsRep();

    /**
     * 执行聚类计算
     */
    public Location[][] execute(int groupCount, List<Location> locations){
        /**
         * 初始化数据仓库
         */
        //设置分组数
        pointsRep.setGroup(groupCount);
        //初始化数据仓库
        pointsRep.initData(locations);

        Location[][] bestList = null;

        /**
         * 执行贪心算法
         */
        /*AlgorithmStrategy algorithmStrategy = new ShortRoute();
        bestList = algorithmStrategy.execute(pointsRep);*/

        /*AlgorithmStrategy algorithmStrategy = new TableRoute();
        bestList = algorithmStrategy.execute(pointsRep);*/

        AlgorithmStrategy algorithmStrategy = new PointGroup();
        bestList = algorithmStrategy.execute(pointsRep);

        /**
         * 对每一个路径进行最优路径规划
         */
        for(int i=0;i<bestList.length;i++){
            /**
             * 将数据封装到数据仓库，执行全排列算法
             */
            List<Location> currList = new ArrayList<>();
            for(int j=0;j<bestList[i].length;j++){
                if(bestList[i][j] == null){
                    break;
                }else{
                    currList.add(bestList[i][j]);
                }
            }

            PointsRep currPointsReq = new PointsRep();
            //初始化仓库
            currPointsReq.initData(currList);
            //设置路径起止点 todo 具体起止点以生产为准
            currPointsReq.setBegin(currList.get(0));
            currPointsReq.setEnd(currList.get(currList.size()-1));


            LOGGER.info("执行最优路径的订单个数：{}",currList.size());

            if(currList.size()< 8){
                AlgorithmStrategy sort = new SortRoute();
                Location[][] sorted = sort.execute(currPointsReq);

                for(int n=0;n<sorted[0].length;n++){
                    bestList[i][n] = sorted[0][n];
                }
            }else{
                AlgorithmStrategy sort = new MultipointRoute();
                Location[][] sorted = sort.execute(currPointsReq);

                /*
                    封装矫正算法入参
                */
                List<Location> list = new ArrayList<>();
                for(int k=0;k<sorted[0].length;k++){
                    list.add(sorted[0][k]);
                }
                PointsRep tempRep = new PointsRep();
                tempRep.initData(list);
                tempRep.setBegin(currPointsReq.getBegin());
                tempRep.setEnd(currPointsReq.getEnd());

                //执行矫正算法
                /*AlgorithmStrategy multiCorr = new MultipointCorrectRoute();
                Location[][] sortedSec = multiCorr.execute(tempRep);*/

                //模拟退火算法
                AlgorithmStrategy multiCorr = new SimulateAnnealRoute();
                Location[][] sortedSec = multiCorr.execute(tempRep);

                for(int n=0;n<sortedSec[0].length;n++){
                    bestList[i][n] = sortedSec[0][n];
                }
            }
            LOGGER.info("路径优化算法结束");
        }

        /*AlgorithmStrategy algorithmStrategy = new InPolygon();
        pointsRep.setBegin(pointsRep.getPoints().get(68));
        pointsRep.setEnd(pointsRep.getPoints().get(104));
        pointsRep.setRadius(new Double(1000));
        LOGGER.info("矩形算法，入参起点：{},入参终点：{}", JSON.toJSONString(pointsRep.getBegin()),JSON.toJSONString(pointsRep.getEnd()));
        bestList = algorithmStrategy.execute(pointsRep);*/

        return bestList;
    }
}
